﻿Imports System.Text.RegularExpressions

Public Class ListArgsHandler
    Implements IArgsTypeHandler

    Public ReadOnly Property DefaultTypeData As String Implements IArgsTypeHandler.DefaultTypeData
        Get
            Return "string"
        End Get
    End Property

    Public ReadOnly Property TypeDataFormat As String Implements IArgsTypeHandler.TypeDataFormat
        Get
            Return "[argumentType:<argumentType's typeData>]..."
        End Get
    End Property

    Public Function ValidateTypeData(typeData As String) As Boolean Implements IArgsTypeHandler.ValidateTypeData
        Dim args As List(Of String) = ParseArguments(typeData)
        For Each arg As String In args
            Dim parts() As String = arg.Split(New Char() {":"c}, 2)
            If parts.Length = 0 Then
                Return False
            End If

            Dim type As ArgType
            If Not [Enum].TryParse(parts(0), type) Then
                Return False
            End If
            Dim argTypeData As String = ""
            If parts.Count = 2 Then
                argTypeData = parts(1)
            Else
                argTypeData = ""
            End If

            Dim handler As IArgHandler = ArgumentManager.instance.GetArgTypeHandler(type)
            If Not handler.ValidateTypeData(argTypeData) Then
                Return False
            End If
        Next
        Return True
    End Function

    Private Function ParseArguments(argsTypeData As String) As List(Of String)
        Dim ret As New List(Of String)
        For Each match As Match In Regex.Matches(argsTypeData, "\[(.*?)\]")
            ret.Add(match.Value.Substring(1, match.Value.Length - 2))
        Next
        Return ret
    End Function

    Public Function GetArgument(argumentIndex As Integer, usage As TokenUsage) As ArgumentDefinition Implements IArgsTypeHandler.GetArgument
        If argumentIndex < usage.Arguments.Count Then
            Return usage.Arguments(argumentIndex)
        End If
        argumentIndex -= usage.Arguments.Count

        Dim args As List(Of String) = ParseArguments(usage.ArgsTypeData)
        If args.Count > 0 Then
            Dim index As Integer = argumentIndex Mod args.Count

            Dim part As String = args(index)
            Dim parts() As String = part.Split(New Char() {":"c}, 2)
            Dim type As ArgType = ArgType.String
            [Enum].TryParse(parts(0), type)

            Dim handler As IArgHandler = ArgumentManager.instance.GetArgTypeHandler(type)
            Dim argument As New ArgumentDefinition
            argument.Name = "Argument " & (argumentIndex + 1).ToString
            argument.Description = ""
            argument.Type = type
            argument.Index = argumentIndex
            If parts.Count >= 2 Then
                argument.TypeData = parts(1)
            End If
            Return argument
        Else
            Dim argument As New ArgumentDefinition
            argument.Name = String.Format("[Unknown {0}]", argumentIndex + 1)
            argument.Description = ""
            argument.Type = ArgType.String
            argument.TypeData = ""
            Return argument
        End If
    End Function

    Public ReadOnly Property HasDynamicArguments As Boolean Implements IArgsTypeHandler.HasDynamicArguments
        Get
            Return True
        End Get
    End Property

    'Public Function GetArgumentName(argumentIndex As Integer, usage As TokenUsage) As String Implements IArgsTypeHandler.GetArgumentName
    '    If argumentIndex < usage.Arguments.Count Then
    '        Return usage.Arguments(argumentIndex).Name
    '    End If
    '    argumentIndex -= usage.Arguments.Count

    '    Return "Argument " & (argumentIndex + 1 + usage.Arguments.Count).ToString
    'End Function
End Class
